#if 0
#include "wifi.h"

#include <string.h>

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"

#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"

#include "freertos/message_buffer.h" //使用消息缓冲区必须要有这个头文件
#include "gatts_table_creat_demo.h"  //线程缓冲区消息

static size_t xBytesSent;
static const TickType_t x100ms = pdMS_TO_TICKS(100);
static char *pcStringToSend = "xa";
static char *pcStringToSend1 = "xb";
static bool lianJieJ = false; // 判断WIFI是否连接标志

static const char *TAG = "wifi: ";

// FreeRTOS事件组，连接成功时发出信号
static EventGroupHandle_t s_wifi_event_group = NULL;
static int s_retry_num = 0;

// 事件回调
static void event_handler(void *arg, esp_event_base_t event_base,
                          int32_t event_id, void *event_data)
{
    // 如果是Wi-Fi事件，并且事件ID是Wi-Fi事件STA_START
    if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START)
    {
        esp_wifi_connect();
    }
    else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED)
    {
        if (lianJieJ)
        {
            //发送WIFI断开消息
            xBytesSent = xMessageBufferSend(socketBufferQ, (void *)pcStringToSend1, strlen(pcStringToSend1), x100ms);
            lianJieJ = false;//WIFI连接标志设断开
        }

        // 如果是Wi-Fi事件，并且事件ID是Wi-Fi断开事件
        /* 如果重试次数小于最大重试次数 */
        if (s_retry_num < LIGHT_ESP_MAXIMUM_RETRY)
        {
            esp_wifi_connect();
            if (s_retry_num > 200)
            {
                vTaskDelay(pdMS_TO_TICKS(60000));
                if (s_retry_num > 400)
                {
                    s_retry_num = 0;
                }
            }
            s_retry_num++;
            ESP_LOGI(TAG, "重试连接AP\n");
            vTaskDelay(pdMS_TO_TICKS(6000));
        }
        else
        {
            xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
        }
        ESP_LOGI(TAG, "连接AP失败\r\n");
    }
    else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP)
    {
        // 如果是IP事件，并且事件ID是IP事件STA_GOT_IP

        // 获取事件结果
        ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
        ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));

        // 发送WIFI成功连接消息到缓存区
        xBytesSent = xMessageBufferSend(socketBufferQ, (void *)pcStringToSend, strlen(pcStringToSend), x100ms);
        lianJieJ = true; // WIFI连接

        // 将重试次数重置为 0；
        s_retry_num = 0;
        // 通过调用 xEventGroupSetBits 函数，将 WIFI_CONNECTED_BIT 设置到事件组中，表示成功连接到 AP
        xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
    }
}

static void wifi_initialize(void)
{
    // 创建一个事件组，用于管理Wi-Fi连接事件。
    s_wifi_event_group = xEventGroupCreate();

    // 初始化 TCP/IP 协议栈。
    ESP_ERROR_CHECK(esp_netif_init());

    // 创建默认事件循环。
    ESP_ERROR_CHECK(esp_event_loop_create_default());

    // 创建默认的Wi-Fi网络接口。
    esp_netif_create_default_wifi_sta();
    // 设置 Wi-Fi 初始化配置为默认配置
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));

    // 注册事件处理器，以处理 Wi-Fi 和 IP 相关事件
    ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
    ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL));
}

static void wifi_station_initialize(char *WIFI_SSID, char *WIFI_PASS)
{
    ESP_LOGI(TAG, "SSID = :%6s password = :%10s\n", WIFI_SSID, WIFI_PASS);
    // 配置WiFi的配置信息
    wifi_config_t wifi_config = {
        .sta = {
            //.ssid = sssidJ,//"cccxxx", //LIGHT_ESP_WIFI_SSID,
            // .password = "chenxin1234567890", //LIGHT_ESP_WIFI_PASS,
            // 启用WPA2模式，常用的WiFi连接方式  WIFI_AUTH_WPA2_PSK
            .threshold.authmode = WIFI_AUTH_WPA_WPA2_PSK,

            .pmf_cfg = {
                .capable = true,
                .required = false},
        }};
    strcpy((char *)wifi_config.sta.ssid, (const char *)WIFI_SSID);
    strcpy((char *)wifi_config.sta.password, (const char *)WIFI_PASS);

    // WiFi工作模式设置为STA
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
    // 设置WiFi工作模式
    ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
    // 启动WiFi
    ESP_ERROR_CHECK(esp_wifi_start());

    ESP_LOGI(TAG, "wifi_station_initialize finished.");

    /* 等待连接建立（WIFI_CONNECTED_BIT）或连接失败的次数达到最大值（WIFI_FAIL_BIT）。
     * 这些位通过 event_handler() 设置（详见上面）*/
    EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, pdFALSE, pdFALSE, portMAX_DELAY);

    /* xEventGroupWaitBits() 返回调用前的 bits，因此我们可以测试实际发生了什么事件。 */
    if (bits & WIFI_CONNECTED_BIT)
    {
        ESP_LOGI(TAG, "连接到 ap SSID:%s password:%s\n", WIFI_SSID, WIFI_PASS);
    }
    else if (bits & WIFI_FAIL_BIT)
    {
        ESP_LOGI(TAG, "无法连接到 SSID:%s, password:%s\n", WIFI_SSID, WIFI_PASS);
    }
    else
    {
        ESP_LOGE(TAG, "意外事件\n");
    }
}

void wifi_init(char *WIFI_SSID, char *WIFI_PASS)
{
    ESP_LOGE(TAG, "app_main");
    // 初始化NVS存储区
    ESP_ERROR_CHECK(nvs_flash_init());
    // Wi-Fi初始化
    ESP_LOGI(TAG, "Wi-Fi initialization");
    wifi_initialize();
    // Wi-Fi Station初始化
    wifi_station_initialize(WIFI_SSID, WIFI_PASS);
}
#elif 1
#include "wifi.h"

#include <string.h>

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"

#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"

#include "freertos/message_buffer.h" //使用消息缓冲区必须要有这个头文件
#include "gatts_table_creat_demo.h"  //线程缓冲区消息

#define DEFAULT_LISTEN_INTERVAL 10
#define DEFAULT_BEACON_TIMEOUT  5
#define DEFAULT_PS_MODE WIFI_PS_MIN_MODEM

static size_t xBytesSent;
static const TickType_t x100ms = pdMS_TO_TICKS(100);
static char *pcStringToSend = "xa";
static char *pcStringToSend1 = "xb";
static bool lianJieJ = false; // 判断WIFI是否连接标志

static const char *TAG = "wifi: ";

// FreeRTOS事件组，连接成功时发出信号
static EventGroupHandle_t s_wifi_event_group = NULL;
static int s_retry_num = 0;

// 事件回调
static void event_handler(void *arg, esp_event_base_t event_base,
                          int32_t event_id, void *event_data)
{
    ESP_LOGI(TAG, "回调运行......\n");
    // 如果是Wi-Fi事件，并且事件ID是Wi-Fi事件STA_START
    if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START)
    {
        ESP_LOGI(TAG, "连接AP......\n");
        esp_wifi_connect();

        printf("连接AP......\n");
    }
    else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED)
    {
        if (lianJieJ)
        {
            // 发送WIFI断开消息
            xBytesSent = xMessageBufferSend(socketBufferQ, (void *)pcStringToSend1, strlen(pcStringToSend1), x100ms);
            lianJieJ = false; // WIFI连接标志设断开
        }

        // 如果是Wi-Fi事件，并且事件ID是Wi-Fi断开事件
        /* 如果重试次数小于最大重试次数 */
        if (s_retry_num < LIGHT_ESP_MAXIMUM_RETRY)
        {
            ESP_LOGI(TAG, "重试连接AP1\n");
            esp_wifi_connect();
            if (s_retry_num > 200)
            {
                vTaskDelay(pdMS_TO_TICKS(60000));
                if (s_retry_num > 400)
                {
                    s_retry_num = 0;
                }
                ESP_LOGI(TAG, "重试连接AP2\n");
            }
            s_retry_num++;
            ESP_LOGI(TAG, "重试连接AP3\n");
            printf("重试连接AP......\n");
            vTaskDelay(pdMS_TO_TICKS(6000));
        }
        else
        {
            xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT); // 设定事件
        }
        ESP_LOGI(TAG, "连接AP失败\r\n");
    }
    else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP)
    {
        // 如果是IP事件，并且事件ID是IP事件STA_GOT_IP

        // 获取事件结果
        ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
        ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
        ESP_LOGI(TAG, "WIFIl 连接成功,发送消息到缓冲区\n");

        // 发送WIFI成功连接消息到缓存区
        xBytesSent = xMessageBufferSend(socketBufferQ, (void *)pcStringToSend, strlen(pcStringToSend), x100ms);
        lianJieJ = true; // WIFI连接

        // 将重试次数重置为 0；
        s_retry_num = 0;
        // 通过调用 xEventGroupSetBits 函数，将 WIFI_CONNECTED_BIT 设置到事件组中，表示成功连接到 AP
        xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
    }
}

static void wifi_initialize(void)
{
    // 创建一个事件组，用于管理Wi-Fi连接事件。
    s_wifi_event_group = xEventGroupCreate();

    // 初始化 TCP/IP 协议栈。
    ESP_ERROR_CHECK(esp_netif_init());

    // 创建默认事件循环。
    ESP_ERROR_CHECK(esp_event_loop_create_default());

    // 创建默认的Wi-Fi网络接口。
    esp_netif_create_default_wifi_sta();
    // 设置 Wi-Fi 初始化配置为默认配置
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));

    // 注册事件处理器，以处理 Wi-Fi 和 IP 相关事件
    ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
    ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL));
}

static void wifi_station_initialize(char *WIFI_SSID, char *WIFI_PASS)
{
    // 配置WiFi的配置信息
    wifi_config_t wifi_config = {
        .sta = {
            //.ssid = sssidJ,//"cccxxx", //LIGHT_ESP_WIFI_SSID,
            // .password = "chenxin1234567890", //LIGHT_ESP_WIFI_PASS,
            // 启用WPA2模式，常用的WiFi连接方式  WIFI_AUTH_WPA2_PSK
            .listen_interval = DEFAULT_LISTEN_INTERVAL,//省电模式下的接收信标的时间间隔
            .threshold.authmode = WIFI_AUTH_WPA_WPA2_PSK,

            .pmf_cfg = {
                .capable = true,
                .required = false},
        }};
    strcpy((char *)wifi_config.sta.ssid, (const char *)WIFI_SSID);     // 设置SSID
    strcpy((char *)wifi_config.sta.password, (const char *)WIFI_PASS); // 设置密码

    // WiFi工作模式设置为STA
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
    // 设置WiFi工作模式
    ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
    // 启动WiFi
    ESP_ERROR_CHECK(esp_wifi_start());
    // WIFI的非活动时间,单位秒
    ESP_ERROR_CHECK(esp_wifi_set_inactive_time(WIFI_IF_STA, DEFAULT_BEACON_TIMEOUT));
    // 节能模式
    esp_wifi_set_ps(DEFAULT_PS_MODE);
    ESP_LOGI(TAG, "wifi chu shi hua OK.\n");

    /* 等待连接建立（WIFI_CONNECTED_BIT）或连接失败的次数达到最大值（WIFI_FAIL_BIT）。
     * 这些位通过 event_handler() 设置（详见上面）*/
    /*xEventGroupWaitBits() 用于等待一个或多个事件位（event bits）变为设定状态*  xEventGroupSetBits*/
    EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,                 // 事件组的句柄，用于指定要等待哪个事件组。
                                           WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, // 一个位掩码，用于指定要等待哪些位变为设定状态
                                           pdFALSE,                            // 如果设置为 pdTRUE，则在函数返回时清除已等待的位。如果设置为 pdFALSE，则不清除
                                           pdFALSE,                            // 如果设置为 pdTRUE，则函数会等待所有指定的位都变为设定状态。如果设置为pdFALSE，则函数会在任何一个指定的位变为设定状态时返回。
                                           portMAX_DELAY);                     // 指定函数等待的最长时间,如果在这个时间内指定的位没有变为设定状态，函数将返回。
                                                           //   如果设置为 portMAX_DELAY，则函数将永远等待，直到指定的位变为设定状态。

    /* xEventGroupWaitBits() 返回调用前的 bits，因此我们可以测试实际发生了什么事件。,返回的是WIFI_CONNECTED_BIT | WIFI_FAIL_BIT的掩码 */
    if (bits & WIFI_CONNECTED_BIT)
    {
        ESP_LOGI(TAG, "连接到 ap SSID:%s password:%s\n", WIFI_SSID, WIFI_PASS);
    }
    else if (bits & WIFI_FAIL_BIT)
    {
        ESP_LOGI(TAG, "无法连接到 SSID:%s, password:%s\n", WIFI_SSID, WIFI_PASS);
    }
    else
    {
        ESP_LOGE(TAG, "意外事件\n");
    }
}

void wifi_init(char *WIFI_SSID, char *WIFI_PASS)
{
    // 初始化NVS存储区
    ESP_ERROR_CHECK(nvs_flash_init());
    // Wi-Fi初始化
    wifi_initialize();
    // Wi-Fi Station初始化
    wifi_station_initialize(WIFI_SSID, WIFI_PASS);
}

#endif